package cg.cmm.base.exceptions;

import org.springframework.util.ObjectUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Map;

public class ApplicationException extends RuntimeException {

    private static final long serialVersionUID = -1618839302595838756L;

    protected String code;

    protected Map<String, Object> map;

    protected String strMessageEN;

    public ApplicationException(Throwable e) {
        super(e);
        Throwable throwable = e;
        Throwable laste = getLastMessage(e);
        String strMessage = throwable.getMessage();
        if (laste != null) {
            if (throwable instanceof NullPointerException) {
                strMessage = "空指针异常，请检查程序代码，进行修改！";
            }
            if (throwable instanceof ClassCastException) {
                strMessage = "类造型异常，请检查程序代码，进行修改！";
            }
            if (throwable instanceof InvocationTargetException) {
                strMessage = "类反射生成异常，请检查程序代码，进行修改！";
            }
            if (throwable instanceof ClassNotFoundException) {
                strMessage = laste.getMessage() + "类未找到或者不存在！";
            }
            if (ObjectUtils.isEmpty(strMessage)) {
                strMessage = laste.toString();
            }
        }
        new ApplicationException(strMessage);
    }

    public ApplicationException(String strMessage) {
        super(strMessage);
    }

    public ApplicationException(String message, Throwable cause) {
        super(message, cause);
    }

    public ApplicationException(String strCode, String strMessage) {
        super(strMessage);
        this.code = strCode;
    }

    public ApplicationException(String strCode, String strMessageCN, String strMessageEN) {
        super(strMessageCN);
        this.strMessageEN = strMessageEN;
        this.code = strCode;
    }

    public ApplicationException(String strCode, String strMessage, Map<String, Object> newMap) {
        super(strMessage);
        this.code = strCode;
        this.map = newMap;
    }

    public String getCode() {
        return code;
    }

    private static Throwable getLastMessage(Throwable e) {
        if (e instanceof UndeclaredThrowableException) {
            UndeclaredThrowableException uth = (UndeclaredThrowableException) e;
            Throwable th = uth.getCause();
            if (th == null) {
                return e;
            }
            return getLastMessage(th);
        }
        if (e instanceof InvocationTargetException) {
            InvocationTargetException uth = (InvocationTargetException) e;
            Throwable th = uth.getCause();
            if (th == null) {
                return e;
            }
            return getLastMessage(th);
        } else {
            return e;
        }

    }
}
